<?php
/**
 * Notes:
 * User: wudg <544038230@qq.com>
 * Date: 2025/10/17 15:48
 */

namespace App\Service\User;


use App\Constants\System\SysStatusConst;
use App\Constants\User\UserAmountTypeConst;
use App\Constants\User\UserCardInfoTypeConst;
use App\Constants\User\UserCardTypeConst;
use App\Dao\Users\UserCategoryDao;
use App\Dao\Users\UsersAccountDao;
use App\Dao\Users\UsersCardDao;
use App\Dao\Users\UsersCardsInfoDao;
use App\Exception\ServiceException;
use App\Model\Users\UsersCardsInfo;
use App\Service\Amount\AmountLogService;
use App\Service\System\UploadOssQiNiuService;
use App\Utils\AmountUtils;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Exception;
class UserMemberService
{

    #[Inject]
    protected UsersCardDao $usersCardDao;


    #[Inject]
    protected UploadOssQiNiuService $uploadOssQiNiuService;


    #[Inject]
    protected UsersAccountDao $usersAccountDao;

    #[Inject]
    protected UsersCardsInfoDao $usersCardsInfoDao;


    /**
     * 会员卡主动核销
     * @param array $params
     * @return array
     */
    public function activeWriteOff(array $params)
    {
        $userInfo = auth()->user();

        $isSubUser  = UserService::isSubAccount($userInfo);
        $searchUid = $userInfo->getId();
        if($isSubUser)
        {
            $searchUid  = $userInfo->soft_id;
        }
        $memberCardInfo = $this->usersCardsInfoDao->getCardInfoByToUidAndId($searchUid,$params['cid']);
        if(!$memberCardInfo) throw new ServiceException("会员卡不存在");
        $accountInfo = $this->usersAccountDao->getInfoByPk($params['account_id']);
        if(!$accountInfo || $accountInfo->uid != $userInfo->getId()) throw new ServiceException("动账账户不存在");
        $signatureUrl = $this->uploadOssQiNiuService->uploadBase64Image($params['signature']);
        $disAmount = AmountUtils::yuanTofen($params['amount']);
        $remark = $params['remark'] ?? '';
        $relation_info = [
            'user_name' => $memberCardInfo->user_name,
            'card_id' => $memberCardInfo->id,
            'signature' => $signatureUrl, //签名文件
        ];
        /**
         * 如果是一次性入账，入账时金额为0，消费信息写入备注中
         */
        if($memberCardInfo->use_type == UserCardTypeConst::ONCE_IN->value && !$isSubUser)
        {
            $amount = 0;
            $relation_info['remark'] = "会员卡消费:{$params['amount']}";
            $remark .= " (划卡消费：{$params['amount']})";
        }else{
            $amount = $disAmount;
        }

        /**
         * 客户签名地址
         */
        Db::beginTransaction();

        try {
            //扣除会员卡对应面值金额
            $memberCardInfo->amount = bcsub($memberCardInfo->amount,$disAmount);
            $memberCardInfo->save();


            //增加账号流水入账
            $amountLogInfo = (new AmountLogService())->saveAmountLogs($userInfo,[
                'uid' => $userInfo->getId(),
                'account_id' =>$accountInfo->id,
                'card_no' =>$memberCardInfo->card_no,
                'amount' =>$amount,
                'save_date' => date("Y-m-d H:i:s"),
                'type' => UserAmountTypeConst::INCOME->value,
                'cate_id' => $params['cate_id'],
                'relation_info' => json_encode($relation_info,JSON_UNESCAPED_UNICODE),
                'remark' => $remark ?? '会员卡核销',
            ]);
            Db::commit();
            $amountLogs = $amountLogInfo->toArray();
            $amountLogs['amount'] = AmountUtils::fenToYuan($amountLogs['amount']);
            $amountLogs['sort_day'] = strtotime(date("Y-m-d", strtotime($amountLogs['save_date'])));
            return $amountLogs;
        }catch (Exception $e)
        {
            Db::rollBack();
            throw new ServiceException($e->getMessage());
        }
    }



    /**
     * 会员卡修改和保存
     * @param array $data
     * @return array
     */
    public function saveMemberUseHandle(array $data)
    {
        $userInfo = auth()->user();
        $cardTmpInfo = $this->usersCardDao->getCardById($data['card_id']);
        if(!$cardTmpInfo) throw new ServiceException("会员卡模板不存在");
        if(!empty($data['id']))
        {
            $memberCardInfo = $this->usersCardsInfoDao->getCardInfoByToUidAndId($userInfo->getId(),$data['id']);
            if(!$memberCardInfo) throw new ServiceException("会员卡不存在");
            $data = [
                'user_name' => trim($data['user_name']),
                'remark' => trim($data['remark']),
                'card_desc' => trim($data['remark']),
            ];
        }else{
            if(empty($userInfo->company_name)) throw new ServiceException("请先完善公司信息");
            $memberCardInfo = new UsersCardsInfo();
            $data = [
                'user_name' => trim($data['user_name']),
                'amount' => $data['amount'],
                'card_desc' => trim($data['remark']),
                'card_name' => $cardTmpInfo->card_name,
                'use_type' => $cardTmpInfo->card_type,
                'card_cids' => $cardTmpInfo->card_cids,
                'card_color' => $cardTmpInfo->card_color,
                'company_name' => $userInfo->company_name,
                'card_no' => UsersCardsInfo::getCardNo(),
                'card_discount' => $cardTmpInfo->card_discount,
                'card_type' => UserCardInfoTypeConst::IMPORT->value,
                'card_id' => $cardTmpInfo->id,
                'to_uid' => $userInfo->getId(),
                'status' => SysStatusConst::NORMAL->value,
            ];
        }
        $res = $memberCardInfo->fill($data)->save();
        if(!$res) throw new ServiceException("会员卡保存失败");
        return $memberCardInfo->toArray();
    }



    /**
     * 获取会员列表
     * @param array $params
     * @return array
     */
    public function getMemberList(array $params = [])
    {

        $userInfo = auth()->user();

        $searchUid = $userInfo->getId();
        if(UserService::isSubAccount($userInfo))
        {
            $searchUid = $userInfo->soft_id;
        }
        $offset = ($params['page'] - 1) * $params['limit'];

        $model = UsersCardsInfo::query()->where('to_uid','=',$searchUid);

        if(!empty($params['keywords']))
        {
            $keywords = trim($params['keywords']);
            $model->where(function($query)use($keywords) {
                $query->where('user_name','like',''.$keywords.'%')->orWhere('card_no','like',''.$keywords.'%')
                    ->orWhere('card_desc','like',''.$keywords.'%');
            });
        }
        $allCids = [];

        $totalNum = $model->count();
        $model->orderBy('id','desc');
        $memberData = $model->limit($params['limit'])->offset($offset)->get()->toArray();
        foreach ($memberData as &$item)
        {
            $item['card_cids'] = json_decode($item['card_cids'],true);
            $item['card_discount'] = AmountUtils::yuanTofen($item['card_discount']);
            $item['amount'] = AmountUtils::fenToYuan($item['amount']);
            $allCids = array_merge($allCids,$item['card_cids']);
        }
        if(count($allCids))
        {
            $allCids = array_unique($allCids);
            $dbCategoryData = (new UserCategoryDao())->getCateByIds($allCids,['id','name']);
            $mapCategoryData = array_column($dbCategoryData,'name','id');
        }
        unset($item);
        foreach ($memberData as &$item)
        {
            if(count($item['card_cids']))
            {
                array_map(function($cid)use($mapCategoryData,&$item) {
                    $item['cate_name'][] = ['id'=>$cid,'name'=>$mapCategoryData[$cid]];
                },$item['card_cids']);
            }
        }

        return [$totalNum,$memberData];
    }
}